#include "bhxjnavigation.h"
BHXJNavTreeNode::BHXJNavTreeNode(QObject *parent):QObject(parent)
{

}
//BHXJNavTreeNode::~BHXJNavTreeNode()
//{

//}

BHXJNavTreeNode * BHXJNavTreeNode::createNode(QString text)
{
    BHXJNavTreeNode *ret=new BHXJNavTreeNode(this);
    ret->text=text;
    ret->level=this->level+1;
    ret->item=new QStandardItem();
    ret->parent=this;

    QVariant val;
    val.setValue(ret);
    ret->item->setData(val,Qt::UserRole);

    return ret;
}



BHXJNavItemDelegate::BHXJNavItemDelegate(QWidget *parent) : QStyledItemDelegate(parent)
{

}
void BHXJNavItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const
{
    const BHXJNavTreeNode *node=index.data(Qt::UserRole).value<BHXJNavTreeNode*>();
    painter->save();

    painter->translate(option.rect.x(),option.rect.y());

    QRectF rect;
    rect.setX(0);
    rect.setY(0);
    rect.setWidth(option.rect.width());
    rect.setHeight(option.rect.height());


    QPen pen;
    if(option.state.testFlag(QStyle::State_Selected))
    {
        pen.setColor(option.palette.highlightedText().color());
        painter->fillRect(rect, option.palette.highlight());
    }
    else if(option.state.testFlag(QStyle::State_MouseOver))
    {
        pen.setColor(option.palette.windowText().color());
        painter->fillRect(rect, option.palette.light());
    }
    else
    {
        pen.setColor(option.palette.windowText().color());
        painter->fillRect(rect, option.palette.window());

    }
    painter->setPen(pen);
    painter->setBrush(Qt::NoBrush);


    int s=option.font.pointSize()/2;
    s=s%2==0?s:s+1;
    int start=static_cast<int>((rect.height()-s)*0.5);
    int offset=start*(node->level-1);

    //未展开加好，展开减号
    if(node->nodes.size()>0)
    {
        painter->save();
        painter->setPen(QPen(pen.color(),2));
        painter->translate(start/2+offset,start);

        QPointF points[4];
        double mid=static_cast<double>(s)/2-0.5;
        points[0]=QPointF(0,mid);
        points[1]=QPointF(s,mid);
        points[2]=QPointF(mid,0);
        points[3]=QPointF(mid,s);
        if(!node->expand)
            painter->drawLines(points,2);
        else {
            painter->drawLines(points,1);
        }
        painter->restore();
    }

    QFontMetrics metric(option.font);
    QString str=node->text;

    painter->setFont(option.font);
    painter->drawText(QPointF(start+s+offset,rect.height()/2+option.font.pointSize()/2),str);
    painter->restore();

    //QStyledItemDelegate::paint(painter, option, index);
}
QSize BHXJNavItemDelegate::sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const
{
    return QStyledItemDelegate::sizeHint(option, index);
}
QWidget *BHXJNavItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
{
    return QStyledItemDelegate::createEditor(parent, option, index);
}
void BHXJNavItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QStyledItemDelegate::setEditorData(editor, index);
}
void BHXJNavItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const
{
    QStyledItemDelegate::setModelData(editor, model, index);
}


BHXJNavProxyModel::BHXJNavProxyModel(QObject *parent):QSortFilterProxyModel(parent)
{

}

bool BHXJNavProxyModel::filterAcceptsRow ( int source_row,const QModelIndex & source_parent )const
{
    QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);
    const BHXJNavTreeNode *node=source_index.data(Qt::UserRole).value<BHXJNavTreeNode*>();

    return getexpland(node);
}



BHXJNavigation::BHXJNavigation(QWidget *parent) : QListView(parent)
{
    node=new BHXJNavTreeNode(this);
    node->expand=true;
    delegate=new BHXJNavItemDelegate(this);
    itemmodel=new QStandardItemModel(this);

    proxymodel=new BHXJNavProxyModel(this);
    proxymodel->setSourceModel(itemmodel);
    proxymodel->setFilterRole(Qt::UserRole);
    proxymodel->setDynamicSortFilter(true);

    this->setItemDelegate(delegate);
    this->setModel(proxymodel);
    this->setEditTriggers(QAbstractItemView::NoEditTriggers);

    connect(this,&BHXJNavigation::clicked,this,&BHXJNavigation::onClicked);
    connect(this,&BHXJNavigation::doubleClicked,this,&BHXJNavigation::onDoubleClicked);
}
BHXJNavTreeNode* BHXJNavigation::addNode(QString text)
{

    if(node->nodes.size()>0)
    {
        return addNode(text,node);
    }
    else
    {
        BHXJNavTreeNode *ret=node->createNode(text);
        itemmodel->insertRow(itemmodel->rowCount(),ret->item);
        node->nodes.append(ret);
        return ret;
    }
}
BHXJNavTreeNode* BHXJNavigation::addNode(QString text,BHXJNavTreeNode* parent)
{
    BHXJNavTreeNode *ret=parent->createNode(text);

    itemmodel->insertRow(findLastIndex(parent)+1,ret->item);
    parent->nodes.append(ret);
    return ret;
}
int BHXJNavigation::findLastIndex(BHXJNavTreeNode *node)
{
    if(node->nodes.size()>0)
    {
        return findLastIndex(node->nodes.last());
    }
    else
    {
        return node->item->row();
    }
}
void BHXJNavigation::removeNode(BHXJNavTreeNode* node)
{
    if(node==this->node)
        return;

    //子节点删除
    for(BHXJNavTreeNode *cn:node->nodes)
    {
        removeNode(cn);
    }

    //本节点删除
    itemmodel->removeRow(node->item->row());
    node->parent->nodes.removeOne(node);
    delete node;
    //delete node->item;
}
void BHXJNavigation::explandAll()
{
    this->explandAll(node,false);
    proxymodel->setFilterFixedString(QString());
}
void BHXJNavigation::explandAll(BHXJNavTreeNode *node,bool upda)
{
    node->expand=true;
    for(BHXJNavTreeNode *cn:node->nodes)
    {
        explandAll(cn,false);
    }
    if(upda)
    {
        proxymodel->setFilterFixedString(QString());
    }

}


void BHXJNavigation::onClicked(const QModelIndex &index)
{
    BHXJNavTreeNode *node=index.data(Qt::UserRole).value<BHXJNavTreeNode*>();
    emit node->clicked();
}
void BHXJNavigation::onDoubleClicked(const QModelIndex &index)
{
    BHXJNavTreeNode *node=index.data(Qt::UserRole).value<BHXJNavTreeNode*>();
    if(node->nodes.size()>0)
    {
        node->expand=!node->expand;
    }
    proxymodel->setFilterFixedString(QString());
}
